package com.john.utils.velocity;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.john.utils.common.StreamUtils;
import com.john.utils.enums.CharsetName;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class VelocityUtils {
    /**
     * UTF-8 字符集
     */
    public static final String UTF8 = "UTF-8";

    /**
     * 初始化vm方法
     */
    public static void initVelocity(){
        try{
            Properties p = new Properties();
            // 加载classpath目录下的vm文件
            p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
            // 定义字符集
            p.setProperty(Velocity.INPUT_ENCODING, UTF8);
            // 初始化Velocity引擎，指定配置Properties
            Velocity.init(p);
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    /**
     * 设置模板变量信息
     * @return 模板列表
     */
    public static VelocityContext prepareContext() {
        return new VelocityContext();
    }

    /**
     * 设置模板变量信息
     * @return 模板列表
     */
    public static VelocityContext prepareContext(JSONArray jsonArray) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("jsonArray", jsonArray);
        return velocityContext;
    }

    /**
     * 设置模板变量信息
     * @return 模板列表
     */
    public static VelocityContext prepareContext(Map<String,Object> map) {
        VelocityContext velocityContext = new VelocityContext();
        for (Map.Entry entry : map.entrySet()) {
            System.out.println("velocityContext.pu()...Key = " + entry.getKey() + ", Value = " + entry.getValue());
            velocityContext.put(entry.getKey().toString(), entry.getValue());
        }
        return velocityContext;
    }

    /**
     * 获取模板信息
     * @return 模板列表
     */
    public static List<String> getTemplateList(List<String> templates){
        if(templates == null){
            templates = new ArrayList<String>();
            templates.add("vm/nginx/nginx.conf.vm");
        }
        return templates;
    }

    /**
     * 获取渲染后的模板内容
     * @param jsonArray
     * @return
     */
    public static String getTemplateContent(JSONArray jsonArray,List<String> templates){
        if(templates == null){
            templates = getTemplateList(null);  //加载示例模板
        }
        initVelocity();
        VelocityContext context = prepareContext(jsonArray);
        // 获取模板列表
        String content = "";
        // 渲染模板
        StringWriter sw;
        for (String template : templates){
            sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, UTF8);
            tpl.merge(context, sw);
            content = sw.toString();
        }
        return content;
    }

    /**
     * 获取渲染后的模板内容
     * @param map
     * @return
     */
    public static String getTemplateContent(Map<String,Object> map,List<String> templates){
        if(templates == null){
            templates = getTemplateList(null);  //加载示例模板
        }
        initVelocity();
        VelocityContext context = prepareContext(map);
        // 获取模板列表
        String content = "";
        // 渲染模板
        StringWriter sw;
        for (String template : templates){
            sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, UTF8);
            tpl.merge(context, sw);
            content = sw.toString();
        }
        return content;
    }

    /**
     * 获取渲染后的模板内容
     * @param jsonArray
     * @return
     */
    public static String getTemplateContent(JSONArray jsonArray,String template){
        if(template == null){
            return null;
        }
        initVelocity();
        VelocityContext context = prepareContext(jsonArray);
        // 渲染模板
        StringWriter sw = new StringWriter();
        Template tpl = Velocity.getTemplate(template, UTF8);
        tpl.merge(context, sw);
        return sw.toString();
    }

    /**
     * 获取渲染后的模板内容
     * @param map
     * @return
     */
    public static String getTemplateContent(Map<String,Object> map,String template){
        if(template == null){
            return null;
        }
        initVelocity();
        VelocityContext context = prepareContext(map);
        // 渲染模板
        StringWriter sw = new StringWriter();
        Template tpl = Velocity.getTemplate(template, UTF8);
        tpl.merge(context, sw);
        return sw.toString();
    }

    /**
     * 获取渲染后的模板内容
     * @param template
     * @return
     */
    public static String getTemplateContent(String template){
        if(template == null){
            return null;
        }
        initVelocity();
        VelocityContext context = prepareContext();
        // 渲染模板
        StringWriter sw = new StringWriter();
        Template tpl = Velocity.getTemplate(template, UTF8);
        tpl.merge(context, sw);
        return sw.toString();
    }

    /**
     * 查看main方法调用示例
     * @return
     */
    public static String showMainContent(){
        return getTemplateContent("vm/nginx/ExamplesMain.vm");
    }

    /**
     * NGINX 配置生成
     */
    public static void gentNginx(){
        //获取参数
        String  dataJson = StreamUtils.InputStreamToString(VelocityUtils.class.getClassLoader().getResourceAsStream("vm/nginx/dataJson.json"),CharsetName.CHAR_UTF_8);
        //解析参数为JSONArray
        JSONArray jsonArray = JSON.parseArray(dataJson);
        //获取渲染后的模板内容
        String templateContent = getTemplateContent(jsonArray,"vm/nginx/nginx.conf.vm");
        //输出内容
        System.out.println(templateContent);
        //未渲染参数的模板内容
        System.out.println(getTemplateContent("vm/nginx/nginx.conf.vm"));
        //查看main方法调用示例
        System.out.println(showMainContent());
    }

    /**
     * Main方法调用示例
     * @param args
     */
    public static void main(String[] args) {
        gentNginx();
    }

}
